/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package simple;

import algorithm.AlgorithmErrorException;
import algorithm.Genotype;
import algorithm.Individual;
import algorithm.Environment;
import algorithm.Phenotype;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Pierre
 */
public class DefaultIndividual implements Individual {
    private Genotype genotype;
    private Map<Environment, Double> fitness;
    private Map<Environment, Phenotype> phenotype;

    public DefaultIndividual(Genotype genotype) {
        this.genotype = genotype;
        fitness = new HashMap<Environment, Double>();
        phenotype = new HashMap<Environment, Phenotype>();
    }
    
    public Genotype getGenotype() {
        return genotype;
    }
/*
    public Individual clone() throws CloneNotSupportedException {
        DefaultIndividual ret = (DefaultIndividual) super.clone();
        ret.genotype = (Genotype) genotype.clone();
        ret.fitness = new HashMap<Environment, Double>();
        for (Entry<Environment, Double> entry : fitness.entrySet()) {
            // make sure we deep-copy the fitness values
            ret.fitness.put(entry.getKey(), (double)entry.getValue());
        }
        ret.phenotype = new HashMap<Environment, Phenotype>();
        for (Entry<Environment, Phenotype> entry : phenotype.entrySet()) {
            // make sure we deep-copy the fitness values
            ret.phenotype.put(entry.getKey(), ((Phenotype)entry.getValue()).clone());
        }
        return ret;
    }
*/
    public Phenotype getPhenotype(Environment environment) throws AlgorithmErrorException {
        if (!phenotype.containsKey(environment)) {
            // calculate the phenotype for this environment
            Phenotype phen = environment.getEncoder().toPhenoType(genotype);
            phenotype.put(environment, phen);
        }
        return phenotype.get(environment);
    }

    public double getFitness(Environment environment) throws AlgorithmErrorException {
         if (!fitness.containsKey(environment)) {
            // calculate the phenotype for this environment
            double fit = environment.getObjectiveFunction().calculateFitness(getPhenotype(environment));
            fitness.put(environment, fit);
        }
        return fitness.get(environment);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DefaultIndividual)) {
            return false;
        }
        return genotype.equals(((DefaultIndividual)obj).getGenotype());
    }


    
}
